﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Net;
using System.Reflection;
using System.Net.Security;
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace AspNetCs.Common
{

    /// <summary>
    /// Encrypt 的摘要说明。
    /// </summary>
    public class Encrypt
    {
        public static byte[] DESKey = new byte[] { 0x82, 0xBC, 0xA1, 0x6A, 0xF5, 0x87, 0x3B, 0xE6, 0x59, 0x6A, 0x32, 0x64, 0x7F, 0x3A, 0x2A, 0xBB, 0x2B, 0x68, 0xE2, 0x5F, 0x06, 0xFB, 0xB8, 0x2D, 0x67, 0xB3, 0x55, 0x19, 0x4E, 0xB8, 0xBF, 0xDD };

        public Encrypt()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }

        #region DES加密解密
        /// <summary>
        /// DES加密
        /// </summary>
        /// <param >待加密字串</param>
        /// <param >32位Key值</param>
        /// <returns>加密后的字符串</returns>
        public string DESEncrypt(string strSource)
        {
            return DESEncrypt(strSource, DESKey);
        }
        public string DESEncrypt(string strSource, byte[] key)
        {
            SymmetricAlgorithm sa = Rijndael.Create();
            sa.Key = key;
            sa.Mode = CipherMode.ECB;
            sa.Padding = PaddingMode.Zeros;
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, sa.CreateEncryptor(), CryptoStreamMode.Write);
            byte[] byt = Encoding.Unicode.GetBytes(strSource);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();
            cs.Close();
            return Convert.ToBase64String(ms.ToArray());
        }
        /// <summary>
        /// DES解密
        /// </summary>
        /// <param >待解密的字串</param>
        /// <param >32位Key值</param>
        /// <returns>解密后的字符串</returns>
        public string DESDecrypt(string strSource)
        {
            return DESDecrypt(strSource, DESKey);
        }
        public string DESDecrypt(string strSource, byte[] key)
        {
            SymmetricAlgorithm sa = Rijndael.Create();
            sa.Key = key;
            sa.Mode = CipherMode.ECB;
            sa.Padding = PaddingMode.Zeros;
            ICryptoTransform ct = sa.CreateDecryptor();
            byte[] byt = Convert.FromBase64String(strSource);
            MemoryStream ms = new MemoryStream(byt);
            CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Read);
            StreamReader sr = new StreamReader(cs, Encoding.Unicode);
            return sr.ReadToEnd();
        }
        #endregion

        #region 一个用hash实现的加密解密方法
        /// <summary>
        /// 加密
        /// </summary>
        /// <param ></param>
        /// <returns></returns>
        public string EncryptStrByHash(string src)
        {
            if (src.Length == 0)
            {
                return "";
            }
            byte[] HaKey = System.Text.Encoding.ASCII.GetBytes((src + "Test").ToCharArray());
            byte[] HaData = new byte[20];
            HMACSHA1 Hmac = new HMACSHA1(HaKey);
            CryptoStream cs = new CryptoStream(Stream.Null, Hmac, CryptoStreamMode.Write);
            try
            {
                cs.Write(HaData, 0, HaData.Length);
            }
            finally
            {
                cs.Close();
            }
            string HaResult = System.Convert.ToBase64String(Hmac.Hash).Substring(0, 16);
            byte[] RiKey = System.Text.Encoding.ASCII.GetBytes(HaResult.ToCharArray());
            byte[] RiDataBuf = System.Text.Encoding.ASCII.GetBytes(src.ToCharArray());
            byte[] EncodedBytes = { };
            MemoryStream ms = new MemoryStream();
            RijndaelManaged rv = new RijndaelManaged();
            cs = new CryptoStream(ms, rv.CreateEncryptor(RiKey, RiKey), CryptoStreamMode.Write);
            try
            {
                cs.Write(RiDataBuf, 0, RiDataBuf.Length);
                cs.FlushFinalBlock();
                EncodedBytes = ms.ToArray();
            }
            finally
            {
                ms.Close();
                cs.Close();
            }
            return HaResult + System.Convert.ToBase64String(EncodedBytes);
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param ></param>
        /// <returns></returns>
        public string DecrypStrByHash(string src)
        {
            if (src.Length < 40) return "";
            byte[] SrcBytes = System.Convert.FromBase64String(src.Substring(16));
            byte[] RiKey = System.Text.Encoding.ASCII.GetBytes(src.Substring(0, 16).ToCharArray());
            byte[] InitialText = new byte[SrcBytes.Length];
            RijndaelManaged rv = new RijndaelManaged();
            MemoryStream ms = new MemoryStream(SrcBytes);
            CryptoStream cs = new CryptoStream(ms, rv.CreateDecryptor(RiKey, RiKey), CryptoStreamMode.Read);
            try
            {
                cs.Read(InitialText, 0, InitialText.Length);
            }
            finally
            {
                ms.Close();
                cs.Close();
            }
            System.Text.StringBuilder Result = new System.Text.StringBuilder();
            for (int i = 0; i < InitialText.Length; ++i) if (InitialText[i] > 0) Result.Append((char)InitialText[i]);
            return Result.ToString();
        }

        /// <summary>
        /// 对加密后的密文重新编码,如果密文长>16,则去掉前16个字符,如果长度小于16,返回空字符串
        /// </summary>
        /// <param ></param>
        /// <returns></returns>
        public string ReEncryptStrByHash(string s)
        {
            string e = (new Encrypt()).EncryptStrByHash(s);
            return ((e.Length > 16) ? e.Substring(16) : "");
        }
        #endregion

        #region Md5加密,生成16位或32位,生成的密文都是大写
        public string Md5To16(string str)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(str)), 4, 8);
            t2 = t2.Replace("-", "");
            return t2;
        }

        //// <summary>
        /// MD5　32位加密
        /// </summary>
        /// <param ></param>
        /// <returns></returns>
        public string Md5To32(string str)
        {
            string pwd = "";
            MD5 md5 = MD5.Create();
            byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
            for (int i = 0; i < s.Length; i++)
            {
                pwd = pwd + s[i].ToString("X");
            }
            return pwd;
        }
        #endregion
    }


    public class EncryptString
    {
        private SymmetricAlgorithm EncryptionService;
        private string IV;  //初始化常量
        private string Key;//加密密匙

        public EncryptString()
        {
            this.EncryptionService = new RijndaelManaged();
            this.Key = "#wangyong86#wang411dongba#5Q622*%#";

            this.IV = "#wangyong86#wang411DFRVGGF#562*%#";
        }
        public EncryptString(string key, string iv)
        {
            this.EncryptionService = new RijndaelManaged();
            this.Key = key;
            this.IV = iv;
        }
        public string Decrypto(string Source)
        {
            try
            {
                byte[] buffer = Convert.FromBase64String(Source);
                MemoryStream stream = new MemoryStream(buffer, 0, buffer.Length);
                this.EncryptionService.Key = this.GetKey();
                this.EncryptionService.IV = this.GetIV();
                ICryptoTransform transform = this.EncryptionService.CreateDecryptor();
                CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Read);
                StreamReader reader = new StreamReader(stream2);
                return reader.ReadToEnd();
            }
            catch
            {
                return string.Empty;
            }
        }

        public string Encrypto(string Source)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(Source);
            MemoryStream stream = new MemoryStream();
            this.EncryptionService.Key = this.GetKey();
            this.EncryptionService.IV = this.GetIV();
            ICryptoTransform transform = this.EncryptionService.CreateEncryptor();
            CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write);
            stream2.Write(bytes, 0, bytes.Length);
            stream2.FlushFinalBlock();
            stream.Close();
            return Convert.ToBase64String(stream.ToArray());
        }

        /// <summary>
        /// 解密字符
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string GetDecrypt(string source)
        {
            EncryptString text = new EncryptString();
            return text.Decrypto(source);
        }
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string GetEncrypt(string source)
        {
            EncryptString text = new EncryptString();
            return text.Encrypto(source);
        }

        private byte[] GetIV()
        {
            string s = this.IV;
            this.EncryptionService.GenerateIV();
            int length = this.EncryptionService.IV.Length;
            if (s.Length > length)
            {
                s = s.Substring(0, length);
            }
            else if (s.Length < length)
            {
                s = s.PadRight(length, ' ');
            }
            return Encoding.ASCII.GetBytes(s);
        }

        private byte[] GetKey()
        {
            string s = this.Key;
            this.EncryptionService.GenerateKey();
            int length = this.EncryptionService.Key.Length;
            if (s.Length > length)
            {
                s = s.Substring(0, length);
            }
            else if (s.Length < length)
            {
                s = s.PadRight(length, ' ');
            }
            return Encoding.ASCII.GetBytes(s);
        }

        /// <summary>
        /// md5加密,不可逆
        /// </summary>
        /// <param name="str">加密字符串</param>
        /// <returns></returns>
        public static string md5(string str)
        {
            return new Encrypt().Md5To16(str);
        }


    }

}
